\chapter{デバッグモード}
\section{デバッグモードとは}
デバッグモードでは、``\indy{むし}{虫}''を取り除くお手伝いを竜がしてくれます。
虫と言うのは、スクリプトファイルに混入してしまった、竜が命令を遂行する時に邪魔になる、
あるいは、不都合を起こす生き物です。その``虫''を取り除くため、デバッグ(de-bug --- 
de-: 取り除く、bug: 虫)と呼ばれます。なお、このデバッグという表記は昔は実際に
コンピュータの中に虫が入ることによって起こったものであったので比喩表現ではありません。

\section{起動方法}
デバッグモードでは基本的にはバッチモードと同様の起動方法です。ただ、\texttt{-d} 
または \verb+--debug+ オプションを付けることだけが異なります。
\begin{lstlisting}
$ cdragon [-d|--debug] [ファイル名...] [-p 引数]
$ gdragon [-d|--debug] [ファイル名...] [-p 引数]
$ kdragon [-d|--debug] [ファイル名...] [-p 引数]
\end{lstlisting}

なお、\texttt{-E} は無視されます。

\section{起動中の操作 --- CDragon の場合}
バッチモードやインタラクティブモードよりも非常に複雑なので、注意して
ください。デバッグモードでは、起動しても実行しません。まずは
\indy{ふれいくほいんと}{ブレークポイント}を設定します。

\subsection{ブレークポイントの設定}
ブレークポイントとは、実行を止める点です。それから実行します。
そうでなければ通常に実行するのと同じになってしまいます。
ブレークポイントは以下のように指定します。指定する時は
デバッグモード専用の命令を使用して行きます。
\begin{lstlisting}[name=debug]
竜: デバッグ命令をどうぞ。
命令> 1行目で停止。
竜: 1 行目だな。
竜: このブレークポイントの番号は 1 だぜよ。
\end{lstlisting}
指定するとこのように番号を教えてくれます。
ブレークポイントを削除するときは、この番号を使って
\begin{lstlisting}[name=debug]
命令> 1番のブレークポイントを削除。
竜: 次からはこの場所では止まらないぜよ。
\end{lstlisting}
とします。行番号以外にも次のような指定方法もあります。
\begin{lstlisting}[name=debug]
命令> 「test.cds」の3行目で停止。
竜: 「test.cds」の 3 行目だな。
竜: このブレークポイントの番号は 2 だぜよ。
\end{lstlisting}
ファイル名も指定します。このとき、今、デバッグしているスクリプト上で
読み込んでいないファイルを指定した場合、ブレークポイントの意味は
無くなりますのでご注意ください。なお、これはエラーにはなりません
\footnote{動的に読み込まれるファイルなどである可能性があるため。}。
\begin{lstlisting}[name=debug]
命令> 関数「何かと言う」で停止。
竜: 関数「何かと言う」だな。
竜: このブレークポイントの番号は 3 だぜよ。
\end{lstlisting}
この場合関数「○○と言う」という命令を呼び出した時、その関数内の1行目
で停止します。ただし、これが Dragon Script で書かれたものでは
ない場合、その関数の直前で停止します。この関数の名前は命令文法叙述記法
(第\ref{command_grammer_reference}部)に記載した方法で指定します。
わからない場合は、「関数検索」という命令を使ってください。
\begin{lstlisting}[name=debug]
命令> 関数検索する。
竜: 一覧表を作るから待ってな。
竜: OKだ。検索したい語を入れてくれ。
検索>
\end{lstlisting}
この検索は通常のマッチングと同じ方法で検索されます。つまり、先ほどの
「何かと言う」という命令を探す場合、
\begin{lstlisting}
「こんにちは」と言え。
「あああ」と言う。
「エッチ」と言わないと怒るわよ。
\end{lstlisting}
などと入力することで検索できます。デバッグモードである場合には、次のように
なります。
\begin{lstlisting}[name=debug]
検索> 「こんにちは」と言え。
竜: えっと「何かと言う」という命令だな?
	y: はい。
	n: いいえ。
答え>
\end{lstlisting}
合っている場合は、\texttt{y} と、間違えた場合は \texttt{n} と入力して
ください。複雑な命令で検索を行った場合、文全体にマッチする物が対象です。
見付からない場合は、そのスクリプトの中で読み込んでいない命令である
可能性があります。そのスクリプトの中で読み込んでいない命令は検索できません。
よろしければ、ブレークポイントに設定するかどうか聞きます。
\begin{lstlisting}[name=debug]
竜: これをブレークポイントに設定するのか?
	y: はい。
	n: いいえ。
答え>
\end{lstlisting}
「はい」を選択すれば、ブレークポイントに設定され、このブレークポイントの番号を
言います。
\begin{lstlisting}[name=debug]
命令> ○○の時、××行目で停止。
竜: ××行目だな。
竜: このブレークポイントの番号は 4 だぜよ。
\end{lstlisting}
これは、条件「○○」が成立する時のみ「××行目で停止」します。もちろん、後半の部分は、
今までの設定の方法が全て使用できます。関数で停止する場合は、引数を利用することがで
きます。

なお、一度使用された番号は、インタープリタが終了するまで、二度と使われなくなります。

\subsection{ブレークポイントの確認}
いままで設定したブレークポイントを確認するには、
\begin{lstlisting}[name=debug]
命令> ブレークポイント一覧を出せ。
竜: 2 番は「test.cds」の 3 行目。
竜: 3 番は「何かと言う」命令。
竜: 4 番は○○が成立する時のみの××行目。
\end{lstlisting}
のように「ブレークポイント一覧を出す」命令を使用します。

\subsection{実行}
\begin{lstlisting}[name=debug]
命令> 実行せよ。
\end{lstlisting}
と命令すると、実行を開始します。

\subsection{ブレークポイントにぶつかったら}
ブレークポイントにぶつかったら次のようになって停止します。
\begin{lstlisting}[name=debug]
竜: 止めるぜよ。
竜: ブレークポイント番号 2 で、
竜: ファイル「test.cds」の 3 行目だぜよ。
竜: 次に実行する命令は、
		答えは 1 + 3。
	だぜよ。
\end{lstlisting}
この場所に問題があることが分かっている場合は、早速編集しましょう。
\begin{lstlisting}[name=debug]
命令> この行を「答えは 1 + 5。」に変更。
竜: 次に実行する命令は
		答えは 1 + 5。
	だぜよ。
\end{lstlisting}
となって変更できます。なお、デバッグモードではインデントを変更するような大がかり
な編集はできません。テキストエディタでお願いします。編集は「この行」のほか前の行を
編集することもできます。

実行して確認してみましょう。1行だけ実行する時は
\begin{lstlisting}[name=debug]
命令> ステップ実行。
竜: 命令は成功したぜよ。
竜: 次は「test.cds」の 4 行目で、
		5回、
	だぜよ。
\end{lstlisting}
を使います。打つのが怠いでしょうから、\texttt{s} だけでも大丈夫です。では
確認しましょう。
\begin{lstlisting}[name=debug]
命令> 答えと言え。
竜: 変数「答え」は整数型で、中身は
		6
	だぜよ。
\end{lstlisting}
のように通常の「言う」命令とは異なり、デバッグに有意義な情報を提供してくれます。
そのかわり、変数名しか指定できません。

おや、次はループのようですね。では、見てみましょう。ところで、\texttt{s} すら
入力するのが億劫だという方もいるでしょう。そんな人には大サービスとして、
何も入力せずに Enter キーを押すと、前回の命令を繰り返すことができます。この辺は
インタラクティブモードと異なりますのでご注意ください。
\begin{lstlisting}[name=debug]
命令> ステップ実行。
竜: 1 回目だぜよ。
竜: 次は「test.cds」の 5 行目で、
			答えに2を足す。
	だぜよ。
\end{lstlisting}
インデントは分かりにくいかもしれません。さて、ループしているとステップ実行では
抜けるのが大変です。なぜなら、
\begin{lstlisting}[name=debug]
命令> ステップ実行。
竜: 命令は成功したぜよ。
竜: 2 回目だぜよ。
竜: 次は「test.cds」の 5 行目で、
			答えに2を足す。
	だぜよ。
\end{lstlisting}
となってしまうから抜けるまでステップ実行を続けないといけません。しかし、
ループや関数から抜けるまでは一度の命令で続けて実行することができます。
\begin{lstlisting}[name=debug]
命令> 抜けるまで実行。
竜: 命令は成功したぜよ。
竜: 次は「test.cds」の 6 行目で、
		100回答えに3を足す。
	だぜよ。
\end{lstlisting}
抜けるまで実行の省略は \texttt{u} (until: 〜まで) です。

今度もステップ実行してみましょう。
\begin{lstlisting}[name=debug]
命令> ステップ実行。
竜: 命令は成功したぜよ。
竜: 次は「test.cds」の 7 行目で、
		答えを3で割る。
	だぜよ。
\end{lstlisting}
今回は通り過ぎてしまいました。1行のみのループではステップ実行でもまとめて
実行されてしまいます。

さて、確認が終って、残りを実行するときや、次の問題のある場所へ飛びたい時は
\begin{lstlisting}[name=debug]
命令> 続けて実行。
竜: 続けるぜよ。
竜: 止めるぜよ。
竜: ブレークポイント番号 3 で、
竜: ファイル「test.cds」の 21 行目だぜよ。
竜: 次に実行する命令は、
		「こんにちは」と言え。
	だぜよ。
\end{lstlisting}
のように「続けて実行」させます。この省略は \texttt{c} (continue: 続ける)
です。

終了すると、終了コードが報告されます。終了コードとは、
\begin{lstlisting}
終わる
終了
\end{lstlisting}
命令では 0 (成功)、
\begin{lstlisting}
エラー終了。
エラーのため終わり。
\end{lstlisting}
命令では 1 (失敗)、
\begin{lstlisting}
×で終了。
×で終わり。
\end{lstlisting}
命令では×に指定した値のことです。その他、Dragon Script の内部エラー
の場合、表\ref{errno}の値が返されることがあります。
\begin{table}[htbp]
\centering
\caption{終了コード一覧}
\label{errno}
\begin{tabular}{p{0pt} r p{0pt} l}
\hline 
 \multicolumn{3}{c}{番号} & \multicolumn{1}{c}{理由} \\
\hline
 &   1 & & 権限がない。 \\
 &   2 & & ファイルやディレクトリが見付からない。 \\
 & 126 & & 内部メモリエラー。 \\
 & 127 & & 命令が見付からない。 \\
\hline
\end{tabular}
\end{table}

\subsection{終了したあとは}
終了したあと、もう一度実行すれば再度デバッグできます。
複数のファイルを同時にデバッグしようとして複数のファイルを指定した場合は、
\begin{lstlisting}
命令> 次のファイルをデバッグする。
竜: わかったぜよ。
竜: 次のファイルは「test2.cds」だぜよ。
竜: ブレークポイントは一度全部削除するぜよ。
\end{lstlisting}
としてください。一度使用したブレークポイントの番号は今後も使用できませんが、
それまでに設定したブレークポイントはすべて削除されます。

また、変更を加えた場合は、その差分を保存することができます。パッチファイルを
作成する場合は \texttt{diff} コマンドを呼び出します。また、オリジナルの
ファイルにデバッグ済であることを意味する \texttt{.debugged} を付けた
ファイルを作成しますので、すでに存在する場合はパッチファイルを
作成できません。ご注意ください。
\begin{lstlisting}
命令> 変更を保存する。
竜: どのように保存するのか?
	o: 完全に置き換える。
	c: コメントアウトして残しておく。
	p: パッチファイルを作成する。
答え>
\end{lstlisting}
完全に置き換える場合、命令は削除されます。パッチファイルは
\texttt{patch} コマンドでパッチすることができます。例えば、
\begin{lstlisting}
$ patch -p[階層違いの数] -b[バックファイル名] <[パッチファイル]
\end{lstlisting}
のようにしてください。

\section{起動中の操作 --- GDragon、KDragon の場合}
操作手順は CDragon の場合とほぼ同様です。ただし、全て GUI で操作することが
できるようになっています。一方でインタラクティブモードと同様に
\ \verb+--like-cdragon+ オプションを指定すると CDragon と同様の方法で操作することが
できます。
